import base64
import re
import ddddocr
import requests


def get_captcha_image():
    """获取验证码图片的base64字符串"""
    try:
        # 添加超时设置，避免请求无响应
        res = requests.get(
            'http://192.168.66.162:38085/stage-api/captchaImage',
            timeout=10
        )
        res.raise_for_status()  # 检查HTTP请求状态
        return res.json()["img"]
    except (requests.exceptions.RequestException, KeyError, ValueError) as e:
        print(f"获取验证码失败: {str(e)}")
        return None


def save_captcha_image(img_str, filename='验证码.jpg'):
    """将base64字符串保存为图片文件"""
    if not img_str:
        print("无效的图片字符串，无法保存")
        return False

    try:
        # 使用上下文管理器自动处理文件关闭
        with open(filename, 'wb') as f:
            imgdata = base64.b64decode(img_str)
            f.write(imgdata)
        return True
    except (base64.binascii.Error, IOError) as e:
        print(f"保存图片失败: {str(e)}")
        return False


def recognize_and_calculate_captcha(filename='验证码.jpg'):
    """识别验证码并计算结果（适用于数学计算类验证码）"""
    try:
        ocr = ddddocr.DdddOcr(show_ad=False)  # 禁用广告弹窗

        with open(filename, 'rb') as f:
            img_bytes = f.read()

        # 识别验证码文本
        res = ocr.classification(img_bytes)
        print(f"识别到的表达式: {res}")

        # 提取数字和运算符（处理可能的识别误差，如'x'替换为'*'）
        expression = re.sub(r'[^\d\+\-\*\/]', '', res)  # 过滤非计算字符
        expression = expression.replace('x', '*').replace('X', '*')  # 替换乘号

        if not expression:
            print("无法提取有效计算表达式")
            return None

        # 计算结果（简单表达式安全计算）
        try:
            result = eval(expression)  # 仅用于可信来源的简单表达式
            print(f"计算结果: {result}")
            return result
        except (SyntaxError, ZeroDivisionError, ArithmeticError) as e:
            print(f"计算失败: {str(e)}，表达式: {expression}")
            return None

    except IOError as e:
        print(f"读取图片失败: {str(e)}")
        return None


if __name__ == '__main__':
    # 流程：获取验证码 -> 保存图片 -> 识别并计算
    captcha_base64 = get_captcha_image()
    if captcha_base64 and save_captcha_image(captcha_base64):
        recognize_and_calculate_captcha()